import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter_account_book/pages/analysis/logic.dart';
import 'package:flutter_account_book/utils/time.dart';
import 'package:flutter_account_book/widgets/Indicator.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';

class ChartsPage extends StatefulWidget {
  final int curId;
  final bool isIncome;
  final DateTimeRange range;
  const ChartsPage(
      {super.key,
      required this.curId,
      required this.isIncome,
      required this.range});

  @override
  State<StatefulWidget> createState() => _ChartsPage();
}

class _ChartsPage extends State<ChartsPage> {
  AnalysisLogic get logic => Get.find<AnalysisLogic>();

  List<Map<String, Object?>> lineList = [];
  List<Map<String, Object?>> pieList = [];

  int touchedIndex = -1;

  @override
  void initState() {
    super.initState();
    logic
        .getTotalAmountPerDay(widget.curId, widget.range, widget.isIncome)
        .then((res) {
      setState(() {
        lineList = res;
      });
    });

    logic
        .getTotalRecordTypeAmountPerDay(
            widget.curId, widget.range, widget.isIncome)
        .then((res) {
      setState(() {
        pieList = res;
      });
    });
  }

  LineChartBarData get lineChartBarData => LineChartBarData(
        isCurved: false,
        // curveSmoothness: 0,
        color: Colors.red,
        barWidth: 4,
        isStrokeCapRound: true,
        dotData: const FlDotData(show: false),
        belowBarData: BarAreaData(show: false),
        spots: List.generate(
            widget.range.end.difference(widget.range.start).inDays + 1,
            (index) {
          double value = 0.0;
          final curDate = widget.range.start.add(Duration(days: index));
          final dateString = DateFormat("yyyy-MM-dd").format(curDate);
          final item = lineList.firstWhereOrNull(
              (item) => (item['record_date'] as String) == dateString);
          if (item != null) {
            value = item['daily_total'] as double;
          }
          return FlSpot(index.toDouble(), value);
        }),
      );
  SideTitles get bottomTitles => SideTitles(
        showTitles: true,
        reservedSize: 32,
        interval: 1,
        getTitlesWidget: bottomTitleWidgets,
      );

  SideTitles leftTitles() => SideTitles(
        showTitles: true,
        interval: 1,
        reservedSize: 40,
      );

  Widget bottomTitleWidgets(double value, TitleMeta meta) {
    const style = TextStyle(
      fontWeight: FontWeight.bold,
      fontSize: 12,
    );
    var index = value.toInt();
    final curDate = widget.range.start.add(Duration(days: index));
    if (index == 0 || isSameDay(curDate, widget.range.end)) {
      final text = DateFormat("yyyy-MM-dd").format(curDate);
      return SideTitleWidget(
        axisSide: meta.axisSide,
        space: 10,
        child: Text(text, style: style, textAlign: TextAlign.center),
      );
    } else {
      return Container();
    }
  }

  LineTouchData get lineTouchData1 => LineTouchData(
        handleBuiltInTouches: true,
        touchTooltipData: LineTouchTooltipData(
          getTooltipColor: (touchedSpot) =>
              Color.fromARGB(255, 241, 147, 146).withOpacity(0.8),
        ),
      );

  @override
  Widget build(BuildContext context) {
    ThemeData themeData = Theme.of(context);
    return ListView(children: [
      Container(
          height: 300,
          padding: EdgeInsets.fromLTRB(0, 60, 40, 0),
          child: LineChart(LineChartData(
              lineTouchData: lineTouchData1,
              gridData: FlGridData(show: false),
              titlesData: FlTitlesData(
                bottomTitles: AxisTitles(
                  sideTitles: bottomTitles,
                ),
                rightTitles: const AxisTitles(
                  sideTitles: SideTitles(showTitles: false),
                ),
                topTitles: const AxisTitles(
                  sideTitles: SideTitles(showTitles: false),
                ),
              ),
              lineBarsData: [lineChartBarData]))),
      SizedBox(height: 30),
      Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children:
            List.generate(pieList.length > 4 ? 4 : pieList.length, (index) {
          return Indicator(
            color: Colors.primaries[index],
            text: pieList[index]["recordType"] as String,
            isSquare: false,
            size: touchedIndex == index ? 18 : 16,
            textColor:
                touchedIndex == index ? themeData.primaryColor : Colors.black,
          );
        }),
      ),
      pieList.length > 4
          ? Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: List.generate(pieList.length - 4, (index) {
                return Indicator(
                  color: Colors.primaries[index + 4],
                  text: pieList[index]["recordType"] as String,
                  isSquare: false,
                  size: touchedIndex == index + 4 ? 18 : 16,
                  textColor: touchedIndex == index + 4
                      ? themeData.primaryColor
                      : Colors.black,
                );
              }),
            )
          : Container(),
      Container(
          height: 300,
          padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
          child: Transform.scale(
              scale: 2.5,
              child: PieChart(PieChartData(
                sections: List.generate(pieList.length, (index) {
                  return PieChartSectionData(
                      showTitle: false,
                      titleStyle: TextStyle(fontSize: 5),
                      color: Colors.primaries[index],
                      value: pieList[index]["totalAmount"] as double,
                      title: pieList[index]["recordType"] as String);
                }),
                sectionsSpace: 1,
                centerSpaceRadius: 0,
                pieTouchData: PieTouchData(
                  touchCallback: (FlTouchEvent event, pieTouchResponse) {
                    setState(() {
                      if (pieTouchResponse == null ||
                          pieTouchResponse.touchedSection == null) {
                        touchedIndex = -1;
                        return;
                      }
                      touchedIndex =
                          pieTouchResponse.touchedSection!.touchedSectionIndex;
                    });
                  },
                ),
              )))),
    ]);
  }
}
